using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/**
 * 通用状态机系统
 * 
 * 功能说明：
 * - 提供通用的状态机实现，支持任意类型的持有者
 * - 实现状态的生命周期管理：进入、更新、退出
 * - 支持状态切换和状态更新
 * 
 * 设计模式：
 * - 状态模式 (State Pattern)
 * - 模板方法模式 (Template Method Pattern)
 */

/**
 * 状态接口
 * 
 * 定义状态的基本行为：
 * - Enter(): 进入状态时调用
 * - Update(): 状态更新时调用
 * - Exit(): 退出状态时调用
 * 
 * 泛型参数 T: 状态机的持有者类型
 */
public interface IState<T>
{
    /**
     * 状态机引用
     * 
     * 说明：
     * - 每个状态都需要持有对状态机的引用
     * - 用于状态内部进行状态切换
     * - 由状态机在切换状态时自动设置
     */
    StateMachine<T> StateMachine { get; set; }

    /**
     * 进入状态
     * 
     * 功能：
     * - 状态被激活时调用
     * - 用于初始化状态相关的资源
     * - 执行状态进入时的逻辑
     */
    void Enter();
    
    /**
     * 更新状态
     * 
     * 功能：
     * - 状态运行期间每帧调用
     * - 处理状态的持续逻辑
     * - 检查状态切换条件
     */
    void Update();
    
    /**
     * 退出状态
     * 
     * 功能：
     * - 状态被切换时调用
     * - 清理状态相关的资源
     * - 执行状态退出时的逻辑
     */
    void Exit();
}

/**
 * 状态基类
 * 
 * 功能：
 * - 提供状态接口的默认实现
 * - 子类可以重写需要的方法
 * - 简化状态类的编写
 * 
 * 泛型参数 T: 状态机的持有者类型
 */
public class BaseState<T> : IState<T>
{
    /**
     * 状态机引用
     * 
     * 说明：
     * - 由状态机在切换状态时自动设置
     * - 状态内部可以通过此引用进行状态切换
     */
    public StateMachine<T> StateMachine { get; set; }

    /**
     * 进入状态 - 默认空实现
     * 
     * 子类可以重写此方法来实现具体的进入逻辑
     */
    public virtual void Enter() { }
    
    /**
     * 更新状态 - 默认空实现
     * 
     * 子类可以重写此方法来实现具体的更新逻辑
     */
    public virtual void Update() { }
    
    /**
     * 退出状态 - 默认空实现
     * 
     * 子类可以重写此方法来实现具体的退出逻辑
     */
    public virtual void Exit() { }
}

/**
 * 状态机类
 * 
 * 功能：
 * - 管理状态的切换和更新
 * - 维护当前状态
 * - 提供状态切换接口
 * 
 * 泛型参数 T: 状态机的持有者类型
 */
public class StateMachine<T>
{
    /**
     * 状态机持有者
     * 
     * 说明：
     * - 状态机所属的对象
     * - 状态可以通过此引用访问持有者的属性和方法
     */
    private T _owner;

    /**
     * 当前状态
     * 
     * 说明：
     * - 当前激活的状态
     * - 每帧调用其Update方法
     * - 切换状态时会调用Exit和Enter方法
     */
    private IState<T> _currentState;

    /**
     * 构造函数
     * 
     * 参数：
     * - owner: 状态机的持有者
     */
    public StateMachine(T owner)
    {
        _owner = owner;
    }

    /**
     * 更新状态机
     * 
     * 功能：
     * - 由持有者每帧调用
     * - 更新当前状态
     * - 如果当前状态为空，则不执行任何操作
     */
    public void Update()
    {
        if (_currentState != null)
        {
            _currentState.Update();
        }
    }

    /**
     * 切换状态
     * 
     * 功能：
     * 1. 退出当前状态（如果存在）
     * 2. 设置新状态
     * 3. 设置状态的StateMachine引用
     * 4. 进入新状态
     * 
     * 参数：
     * - state: 要切换到的新状态
     */
    public void ChangeState(IState<T> state) 
    {
        // 退出当前状态（如果存在）
        if (_currentState != null)
        {
            _currentState.Exit();
        }
        
        // 设置新状态
        _currentState = state;
        
        // 设置状态的StateMachine引用
        _currentState.StateMachine = this;
        
        // 进入新状态
        _currentState.Enter();
    }
}